﻿Option Explicit On
Option Strict On
Option Infer Off

Public Class SpriteSheetEditor
    Dim frames() As globals.simpleIO
    Dim framimgs() As Image
    Dim currframe As UInteger = 0
    Dim numofframes As UInteger = 0
    Dim resized As Boolean = False
    Private Sub SpriteSheetEditor_Load(sender As Object, e As EventArgs) Handles MyBase.Load
        Me.Icon = My.Resources.ikon_kicsi
        numofframes = 0
        currframe = 0
        OpenPNGDialog.Multiselect = True
        ReDim frames(1) 'Clear the array
        ReDim framimgs(1) 'Clear the array
        lb_filelist.Items.Clear()
        txt_picheight.Text = System.Convert.ToString(32)
        txt_picwidth.Text = System.Convert.ToString(32)
    End Sub

#Region "Buttons"
    Private Sub btn_exit_Click(sender As Object, e As EventArgs) Handles btn_exit.Click
        PreviewPlayerTimer.Enabled = False
        lb_filelist.Items.Clear()
        ReDim frames(1) 'Clear the array to save memory
        ReDim framimgs(1) 'Clear the array to save memory
        Me.Close()
    End Sub
    Private Sub btn_addfiles_Click(sender As Object, e As EventArgs) Handles btn_addfiles.Click
        Try
            If OpenPNGDialog.ShowDialog = Windows.Forms.DialogResult.OK And System.IO.Path.GetExtension(OpenPNGDialog.FileName) = ".png" Then
                Dim file As String
                Dim i As Integer = -1
                For Each file In OpenPNGDialog.FileNames
                    Try
                        i += 1
                        ReDim Preserve frames(i)
                        ReDim Preserve framimgs(i)
                        With frames(i)
                            .name = System.IO.Path.GetFileName(file)
                            .path = System.IO.Path.GetDirectoryName(file)
                            framimgs(i) = System.Drawing.Image.FromFile(file)
                            lb_filelist.Items.Add(.name)
                        End With
                        numofframes = System.Convert.ToUInt32(numofframes + 1)
                        globals.sheet = Nothing
                        resized = False
                    Catch ex As System.Security.SecurityException
                        ' The user lacks appropriate permissions to read files, discover paths, etc.
                        MessageBox.Show("Security error. Please contact your administrator for details.\n\n" +
                            "Error message: " + ex.Message + "\n\n" +
                            "Details (send to Support):\n\n" + ex.StackTrace)
                    End Try
                Next file
            End If
        Catch ex As Exception
            MessageBox.Show(ex.Message)
        End Try
    End Sub
    Private Sub btn_clear_Click(sender As Object, e As EventArgs) Handles btn_clear.Click
        lb_filelist.Items.Clear()
        ReDim frames(1)
        ReDim framimgs(1) 'Clear the array
        numofframes = 0
        currframe = 0
        globals.sheet = Nothing
    End Sub
    Private Sub btn_delete_Click(sender As Object, e As EventArgs) Handles btn_delete.Click
        Dim i As ULong = 0
        Dim index As UInteger = System.Convert.ToUInt32(lb_filelist.SelectedIndex)
        For i = 0 To System.Convert.ToUInt64(frames.Length) Step 1
            With frames(System.Convert.ToInt32(i))
                If System.Convert.ToString(lb_filelist.SelectedItem) = .name Then
                    lb_filelist.Items.Remove(.name)
                    .name = String.Empty
                    .path = String.Empty
                    framimgs(System.Convert.ToInt32(i)) = Nothing
                    numofframes = System.Convert.ToUInt32(numofframes + 1)
                    lb_filelist.SelectedIndex = System.Convert.ToInt32(index)
                    Exit Sub
                End If
            End With
        Next i
    End Sub
    Private Sub btn_moveup_Click(sender As Object, e As EventArgs) Handles btn_moveup.Click
        Dim i As ULong = 0
        For i = 0 To System.Convert.ToUInt64(frames.Length) Step 1
            If lb_filelist.SelectedIndex > 0 Then
                With frames(System.Convert.ToInt32(i))
                    If System.Convert.ToString(lb_filelist.SelectedItem) = .name Then
                        Dim temp As globals.simpleIO
                        Dim tempimg As Image
                        tempimg = framimgs(System.Convert.ToInt32(i - 1))
                        temp = frames(System.Convert.ToInt32(i - 1))
                        framimgs(System.Convert.ToInt32(i - 1)) = framimgs(System.Convert.ToInt32(i))
                        frames(System.Convert.ToInt32(i - 1)) = frames(System.Convert.ToInt32(i))
                        framimgs(System.Convert.ToInt32(i)) = tempimg
                        frames(System.Convert.ToInt32(i)) = temp
                        Dim listboxindex As UInteger = System.Convert.ToUInt32(lb_filelist.SelectedIndex - 1)
                        lb_filelist.Items.Insert(System.Convert.ToInt32(listboxindex), lb_filelist.SelectedItem)
                        lb_filelist.Items.RemoveAt(lb_filelist.SelectedIndex)
                        lb_filelist.SelectedIndex = System.Convert.ToInt32(listboxindex)
                        Exit Sub
                    End If
                End With
            End If
        Next i
    End Sub
    Private Sub btn_movedown_Click(sender As Object, e As EventArgs) Handles btn_movedown.Click
        Dim i As ULong = 0
        For i = 0 To System.Convert.ToUInt64(frames.Length) Step 1
            If lb_filelist.SelectedIndex > lb_filelist.Items.Count - 1 Then
                With frames(System.Convert.ToInt32(i))
                    If System.Convert.ToString(lb_filelist.SelectedItem) = .name Then
                        Dim temp As globals.simpleIO
                        Dim tempimg As Image
                        tempimg = framimgs(System.Convert.ToInt32(i + 1))
                        temp = frames(System.Convert.ToInt32(i + 1))
                        framimgs(System.Convert.ToInt32(i + 1)) = framimgs(System.Convert.ToInt32(i))
                        frames(System.Convert.ToInt32(i + 1)) = frames(System.Convert.ToInt32(i))
                        framimgs(System.Convert.ToInt32(i)) = tempimg
                        frames(System.Convert.ToInt32(i)) = temp
                        Dim listboxindex As UInteger = System.Convert.ToUInt32(lb_filelist.SelectedIndex + 2)
                        lb_filelist.Items.Insert(System.Convert.ToInt32(listboxindex), lb_filelist.SelectedItem)
                        lb_filelist.Items.RemoveAt(lb_filelist.SelectedIndex)
                        lb_filelist.SelectedIndex = System.Convert.ToInt32(listboxindex - 1)
                        Exit Sub
                    End If
                End With
            End If
        Next i
    End Sub

    Private Sub btn_startpreview_Click(sender As Object, e As EventArgs) Handles btn_startpreview.Click
        PreviewPlayerTimer.Enabled = True
    End Sub
    Private Sub btn_stoppreview_Click(sender As Object, e As EventArgs) Handles btn_stoppreview.Click
        PreviewPlayerTimer.Enabled = False
    End Sub
    Private Sub btn_create_Click(sender As Object, e As EventArgs) Handles btn_create.Click
        Try
            Dim i As Integer

            If Not resized Then
                If MsgBox("The images have not been resized. Do you want to continue?", MsgBoxStyle.OkCancel) <> MsgBoxResult.Ok Then
                    Exit Sub
                End If
            End If

            If lb_filelist.Items.Count = 0 Then
                MessageBox.Show("There are no images to be compiled into a sprite sheet. Please add images!", "ERROR!")
                Exit Sub
            End If

            Dim culomns As UInteger = System.Convert.ToUInt32(txt_numofcolumns.Text)
            Dim rows As UInteger = System.Convert.ToUInt32(numofframes \ culomns) + System.Convert.ToUInt32(IIf(numofframes Mod culomns <> 0, 1, 0))
            Dim x As UInteger = 0
            Dim y As UInteger = 0

            If System.Convert.ToInt32(culomns * System.Convert.ToInt32(txt_picwidth.Text)) > 2048 Then
                MessageBox.Show("The sprite sheet's vertical resolution cannot be greater than 2048!", "ERROR!")
                Exit Sub
            End If

            If System.Convert.ToInt32(rows * System.Convert.ToInt32(txt_picwidth.Text)) > 2048 Then
                MessageBox.Show("The sprite sheet's horizontal resolution cannot be greater than 2048!", "ERROR!")
                Exit Sub
            End If

            globals.sheet = New Bitmap(System.Convert.ToInt32(culomns * System.Convert.ToInt32(txt_picwidth.Text)), System.Convert.ToInt32(rows * System.Convert.ToInt32(txt_picwidth.Text)))
            Dim graphicsobject As Graphics = Graphics.FromImage(globals.sheet)

            For i = 0 To System.Convert.ToInt32(numofframes - 1) Step 1
                graphicsobject.DrawImage(framimgs(System.Convert.ToInt32(i)), x, y)
                x = x + System.Convert.ToUInt32(txt_picwidth.Text)
                If x = System.Convert.ToUInt32(culomns * System.Convert.ToDouble(txt_picwidth.Text)) Then
                    y = y + System.Convert.ToUInt32(txt_picwidth.Text)
                    x = 0
                End If
            Next i
            PreviewSpriteSheet.ShowDialog()
        Catch ex As Exception
            MessageBox.Show(ex.Message)
        End Try
    End Sub
    Private Sub btn_resizeimages_Click(sender As Object, e As EventArgs) Handles btn_resizeimages.Click
        Dim i As Integer
        For i = 0 To System.Convert.ToInt32(numofframes - 1) Step 1
            If Not (framimgs(i).Height = System.Convert.ToInt32(txt_picheight.Text) AndAlso framimgs(i).Width = System.Convert.ToInt32(txt_picwidth.Text)) Then
                framimgs(i) = globals.ResizeImage(framimgs(i), System.Convert.ToInt32(txt_picwidth.Text), System.Convert.ToInt32(txt_picheight.Text))
            End If
        Next i
        resized = True
        MessageBox.Show("The images have been successfully resized!", "SUCCESS!")
    End Sub
    Private Sub btn_save_Click(sender As Object, e As EventArgs) Handles btn_save.Click
        Try
            If SavePNGDialog.ShowDialog = Windows.Forms.DialogResult.OK And System.IO.Path.GetExtension(SavePNGDialog.FileName) = ".png" Then
                If Not My.Computer.FileSystem.FileExists(SavePNGDialog.FileName) Then globals.sheet.Save(SavePNGDialog.FileName)
                globals.sheet = Nothing
            End If
        Catch ex As Exception

        End Try
    End Sub
#End Region

#Region "Play Animation"
    Private Sub PreviewPlayerTimer_Tick(sender As Object, e As EventArgs) Handles PreviewPlayerTimer.Tick
        Try
            currframe = System.Convert.ToUInt32(currframe + 1)

            If (numofframes > 0 AndAlso currframe <= numofframes) Then
                If (Not framimgs(System.Convert.ToInt32(currframe - 1)) Is Nothing) Then _
                    pb_preview.Image = framimgs(System.Convert.ToInt32(currframe - 1))
            Else
                currframe = 0
            End If
        Catch ex As Exception
            MessageBox.Show(ex.Message)
        End Try
    End Sub
    Private Sub delay_ValueChanged(sender As Object, e As EventArgs) Handles delay.ValueChanged
        PreviewPlayerTimer.Interval = System.Convert.ToInt32(delay.Value)
    End Sub
#End Region

    Private Sub txt_nums_TextChanged(sender As Object, e As EventArgs) Handles txt_numofcolumns.TextChanged, txt_picheight.TextChanged, txt_picwidth.TextChanged
        Dim i As Integer = 0    'Variable of the For cycle.
        Dim value As String = String.Empty  'Numeric value of the textbox's text.
        Dim enteredvalue As String = CType(sender, TextBox).Text   'Entered value of the textbox.

        'Check to see if the textbox only contains numbers to see if there is a problem.
        If Not Integer.TryParse(enteredvalue, Nothing) Or enteredvalue = String.Empty Then
            ErrorProvider.SetError(CType(sender, TextBox), "This field can only contain numbers.")
            For i = 0 To enteredvalue.Length - 1 Step 1
                If Integer.TryParse(enteredvalue.Substring(i, 1), Nothing) Then
                    value += enteredvalue.Substring(i, 1)
                End If
            Next i
            CType(sender, TextBox).Text = value
        Else
            ErrorProvider.SetError(CType(sender, TextBox), Nothing)
        End If
    End Sub
End Class